package com.boco.pciv.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ICaptcha;
import cn.hutool.core.util.StrUtil;
import com.boco.pciv.core.AppProperties;
import com.boco.pciv.core.annotion.Anonymous;
import com.boco.pciv.core.entity.Constants;
import com.boco.pciv.core.exception.PcivException;
import com.boco.pciv.core.security.LoginUser;
import com.boco.pciv.entity.sys.UserInfo;
import com.boco.pciv.entity.sys.UserOnlineInfo;
import com.boco.pciv.service.shiro.ShiroUtils;
import com.boco.pciv.service.sys.IResService;
import com.boco.pciv.service.sys.IUserOnlineService;
import com.boco.pciv.service.sys.IUserService;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * Created by CC on 2017/6/6.
 */
@Controller
public class HomeController extends PcivController {
    //logger
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    @Autowired
    IUserService userSrv;
    @Autowired
    IUserOnlineService userOnlineSrv;
    @Autowired
    private IResService resSrv;
    @Autowired
    private AppProperties appProperties;

    /**
     * 通用页面跳转
     * @param url
     * @return
     */
    @RequestMapping("{url}.shtml")
    public String page(@PathVariable("url") String url) {
        return  url;
    }
    /**
     * 通用页面跳转(二级目录)
     * @param module
     * @param url
     * @return
     */
    @RequestMapping("{module}/{url}.shtml")
    public String page(@PathVariable("module") String module,@PathVariable("url") String url) {
        return module + "/" + url;
    }

    @RequestMapping("/")
    public String home(Map<String, Object> model){
        model.put("sysName", appProperties.getName());
        return "redirect:/index.html";
    }

    @RequestMapping("/blank")
    public String blank(){
        return "_blank";
    }

    @RequiresAuthentication
    @RequestMapping("/index")
    public String index(Map<String, Object> model){
        //获取用户信息
        LoginUser user= getCurUser();
        if (user==null){
            //重定向
            return "redirect:/login";
        }
        else {
            model.put("sysName", appProperties.getName());
            //用户信息
            model.put("curUser", user);
            model.put("menulst", resSrv.getResTreeByUser(user.getUserId()));

            return "index.html";
        }
    }
    @Anonymous
    @RequestMapping("/login")
    public String login(Map<String, Object> model){
        model.put("sysName", appProperties.getName());
        return "login";
    }

    @Anonymous
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(String username,String password,String verCode,Map<String, Object> model,HttpServletRequest request){
        model.put("sysName", appProperties.getName());
        //检查验证码
//        if (StrUtil.isBlank(verCode)){
//            model.put("error","验证码不正确");
//            return  "login";
//        }

//        String realVerCode = ToolUtil.toStr(getSessionData(Constants.CAPTCHA_SESSION_KEY));
//        if (!realVerCode.equalsIgnoreCase(verCode)){
//            model.put("error","验证码不正确");
//            return  "login";
//        }


        try{
            Subject subject = ShiroUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            subject.login(token);
        }catch (UnknownAccountException e) {
            model.put("error","用户名或密码不正确");
            return  "login";
        }catch (IncorrectCredentialsException e) {
            model.put("error","用户名或密码不正确");
            return  "login";
        }catch (PcivException e) {
            model.put("error",e.getMsg());
            return  "login";
        }

        LoginUser u = getCurUser();
        //判断是否第一次登录
        if (!"admin".equals(username)) {
            if (u.getLastLoginTime()==null) {
                //设置登录用户id 修改密码页面用
                setSessionData(Constants.CurrentUserId,username);

                //密码修改
                logger.info("用户 {} 首次登录，需要修改密码！", u.getUserId());
                return "redirect:modifyPassword?type=new";
            }
        }

        //更新登录时间
        userSrv.updateLoginTime(username);

        //记录在线人数
        UserOnlineInfo onlineinfo = new UserOnlineInfo();
        onlineinfo.setSessionId(request.getSession().getId());
        onlineinfo.setUserId(username);
        onlineinfo.setDeptId(u.getDeptId());
        onlineinfo.setLoginIp(getUserIp());
        userOnlineSrv.delete(username);
        userOnlineSrv.add(onlineinfo);
        model.put("curUser",u);
        addLoginLog();
        logger.info("用户 {} 登录成功！",username);
        //检查用户名密码
        return "redirect:/index.html";
    }

    @Anonymous
    @RequiresAuthentication
    @RequestMapping(value="/modifyPassword",produces = {"text/html;charset=UTF-8"},method = RequestMethod.GET)
    public String modifyPassword(String type,Map<String, Object> model){
        model.put("type",type);
        model.put("uid",getCurUserId());
        return  "modifyPassword";
    }

    @RequiresAuthentication
    @RequestMapping("/main")
    public String welcome(Map<String, Object> model){
        model.put("userId",getCurUserId());
        LoginUser user = getCurUser();
        model.put("userName",user.getUserName());
        model.put("lastLoginTime",user.getLastLoginTime());
        return "main";
    }

    @RequestMapping(value="/logout",produces = {"text/html;charset=UTF-8"},method = RequestMethod.GET)
    public String logout(HttpServletRequest request){
        try {
            ShiroUtils.logout();
            String uid = getCurUserId();
            if (!StrUtil.isBlank(uid)) {
                userOnlineSrv.delete(uid);
                logger.info("用户 {} 退出成功！", uid);
            }
        }
        catch (Exception e){
            logger.warn("退出处理失败",e);
        }
        return "redirect:/login";
    }
    @RequiresAuthentication
    @RequestMapping(value="/userInfo",produces = {"text/html;charset=UTF-8"})
    public String userInfo(Map<String, Object> model){
        String uid = getCurUserId();
        UserInfo result= userSrv.getOneByUserId(uid);
        model.put("user",result);
        return  "userInfo";
    }

    @RequiresAuthentication
    @RequestMapping(value="/addOperLog",produces = {"text/html;charset=UTF-8"},method = RequestMethod.POST)
    @ResponseBody
    public void addOperLog(String moduleId,String action,String logInfo){
        if (!checkUserLogin()) {
            return;
        }
        addOperationLog(moduleId,action,logInfo);
    }

    @RequestMapping(value="/getOnLineUserCount",produces = {"text/html;charset=UTF-8"},method = RequestMethod.GET)
    @ResponseBody
    public String getOnLineUserCount() {
        //在线人员查询
        //刷新当前人员
        userOnlineSrv.refresh(getCurUserId());
        //获取
        Integer cnt = userOnlineSrv.getOnlineCount();
        if (cnt == null) {
            return "0";
        } else {
            return cnt.toString();
        }
    }


    @Anonymous
    @RequestMapping("/patchcaimg")
    public void getPatchca(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //hutool
        //ICaptcha captcha = CaptchaUtil.createLineCaptcha(120,40,4,50);
        ICaptcha captcha = CaptchaUtil.createShearCaptcha(120, 40, 4, 2);

        String token =captcha.getCode();
        setSessionData(Constants.CAPTCHA_SESSION_KEY, token);

        setResponseHeaders(response);
        captcha.write(response.getOutputStream());
        logger.debug("session:{},captchaToken:{}", getSessionId(), token);
    }
    protected void setResponseHeaders(HttpServletResponse response) {
        response.setContentType("image/png");
        response.setHeader("Cache-Control", "no-cache, no-store");
        response.setHeader("Pragma", "no-cache");
        long time = System.currentTimeMillis();
        response.setDateHeader("Last-Modified", time);
        response.setDateHeader("Date", time);
        response.setDateHeader("Expires", time);
    }

}
